<?php

namespace addons\xiservice\controller;

use addons\xiservice\library\Config;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Http\StreamResponse;
use EasyWeChat\Kernel\Exceptions\HttpException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use think\Controller;
use think\Exception;
use think\Log;
use think\exception\ThrowableError;
use think\Db;
use app\common\model\xiservice\User as XiserviceUser;
use app\common\model\xiservice\Order as UserOrder;


use AlibabaCloud\SDK\Dyplsapi\V20170525\Models\BindAxnRequest;

use AlibabaCloud\SDK\Dyplsapi\V20170525\Dyplsapi;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;

use Darabonba\OpenApi\Models\Config as AlibabaConfig;
use AlibabaCloud\SDK\Dyplsapi\V20170525\Models\BindAxbRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;

class WeixinMini extends Controller
{
    public $app;
    public $miniapp;

    public function _initialize()
    {
        parent::_initialize();

        $this->app = Factory::miniProgram(Config::load());
        $this->miniapp = Factory::payment(Config::load());
    }

    /**
     * 登录
     * @param $code
     * @return mixed
     * @throws Exception
     * @throws ThrowableError
     */
    public function wxlogin($code)
    {
        try {
            $result = $this->app->auth->session($code);
        } catch (ThrowableError $e) {
            return ["status" => false, "data" => [], "msg" => $e->getMessage()];
        } catch (HttpException $e) {
            return ["status" => false, "data" => [], "msg" => $e->getMessage()];
        } catch (Exception $e) {
            return ["status" => false, "data" => [], "msg" => $e->getMessage()];
        }
        return $result;
    }

    /**
     * 微信信息解密
     * @param $session_key
     * @param $iv
     * @param $encryptedData
     * @return mixed
     * @throws Exception
     * @throws ThrowableError
     */
    public function wxEncrypted($session_key, $iv, $encryptedData)
    {
        try {
            $result = $this->app->encryptor->decryptData($session_key, $iv, $encryptedData);

        } catch (ThrowableError $e) {
            throw $e;
        } catch (Exception $e) {
            throw $e;
        }
        return $result;
    }


    /**
     * 获取access_token
     */
    public function get_token()
    {
        $token = $this->app->access_token->getToken();
        return $token;
    }

    /**
     * 获取小程序码-A
     */
    public function getlimited($page)
    {

        $response = $this->app->app_code->get($page);
        $resfilename = '';
        if ($response instanceof StreamResponse) {
            $resfilename = $response->getBodyContents();
        }
        return $resfilename;
    }


    /**
     * 获取小程序码-B
     */
    public function getUnlimited($scene, $page)
    {

        $response = $this->app->app_code->getUnlimit($scene, ['page' => $page]);
        $resfilename = '';
        if ($response instanceof StreamResponse) {
            $resfilename = $response->getBodyContents();
        }
        return $resfilename;
    }

    /**
     * 发送订阅模板
     */
    public function subscribeMessage($data)
    {
        $response = $this->app->subscribe_message->send($data);
        // Db::name('testmsg')->insert(['content'=> json_encode($response),'content_data'=>130]);
    }

    /**
     * 请求过程中因为编码原因+号变成了空格
     * 需要用下面的方法转换回来
     */
    public function define_str_replace($data)
    {
        return str_replace(' ', '+', $data);
    }

    /**
     * 统一下单 商城订单
     * @param array $orderInfo 订单信息：[
     * 'trade_type'=>'JSAPI',// 请对应换成你的支付方式对应的值类型
     * 'out_trade_no'=>'master202019920904',//订单号
     * 'body'=>'购买商品',//
     * 'total_fee'=>1,//支付金额，这边传单位为元的就可以。
     * 'openid'=>'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o',//用户openID
     * ]
     * @return mixed
     */
    public function union_order($orderInfo)
    {
        $orderInfo['time_expire'] = date('YmdHis', strtotime('+30 minutes'));
        $orderInfo['total_fee'] = $orderInfo['total_fee'] * 100;
        try {
            $result = $this->miniapp->order->unify($orderInfo);
            // dump($result);

        } catch (InvalidArgumentException $e) {
            return ["status" => false, "data" => [], "msg" => $e->getMessage()];
        }
        if ($result['return_code'] == 'FAIL') {
            return ['status' => false, 'msg' => $result['return_msg']];
        } else {
            $jssdk = $this->miniapp->jssdk;
            if ($result['result_code'] == 'FAIL') {
                return ['status' => false, 'msg' => ''];
            }
            if ($orderInfo['trade_type'] == 'APP') {
                $config = $jssdk->appConfig($result['prepay_id']);
            } else {
                $config = $jssdk->sdkConfig($result['prepay_id']);
            }
            return ['status' => true, 'wxconfig' => json_encode($config)];
        }
    }
    public function updateorderamount($order)
    {
        // $order = UserOrder::where('order_no', $order_no)->find();

        $worker = XiserviceUser::where("id",  $order['worker_id'])->find();

             //推送订阅消息
             $msg = new \app\common\model\xiservice\Message();
             $msg->sendOrderMessage($order, 8);
             $userA = Db::name('user')->where(['id'=>$order['user_id']])->find();
             $userB = Db::name('user')->where(['id'=>$worker['user_id']])->find();
             $this->bindAxb($userA['mobile'],$userB['mobile'],$userB['id'],$userA['id']);
        $this->success('处理成功', 1);
    }

    public function bindAxb($phoneNoA,$phoneNoB,$useridB,$useridA)
    {
        $config = new AlibabaConfig([
            "accessKeyId" => "LTAI5tJ4dtHvxJXpDAJTRuFN",
            "accessKeySecret" => "9Aafg08e9GCVFGB9ZJhYMSvYBzRA0U"
        ]);
        $config->endpoint = "dyplsapi.aliyuncs.com";
        $client = new Dyplsapi($config);
        $timestamp_plus_5_minutes = time() + 5 * 60;
        $added_time = date('Y-m-d H:i:s',$timestamp_plus_5_minutes);
        $bindAxnRequest = new BindAxnRequest([
            "poolKey" => "FC100000180222320",
            "phoneNoA" =>$phoneNoA,
            "phoneNoB" => $phoneNoB,
            "expiration" => $added_time
        ]);
        $runtime = new RuntimeOptions([]);
        try {
            $response= $client->bindAxnWithOptions($bindAxnRequest, $runtime);
            $json = json_encode($response);
            $array = json_decode($json, true);

            $json2 = json_encode($array['body']);
            if($array && $array['body'] && $array['body']['secretBindDTO'])
            {
                $virtual_number = $array['body']['secretBindDTO']['secretNo'];
                Db::name('xiservice_user')->where(['user_id'=>$useridB])->update(["virtual_number"=>$virtual_number]);
                Db::name('xiservice_user')->where(['user_id'=>$useridA])->update(["virtual_number"=>$virtual_number]);
            }
        }
        catch (\Exception $error) {
           
        }
    }
    /**
     * 支付回调
     */
    public function order_notify()
    {
        $response = $this->miniapp->handlePaidNotify(function ($message, $fail) {

            $order_no = $message['out_trade_no'];
            $transaction_id = $message['transaction_id'];
            log::write(json_encode($message), 'debug');
            $type = 0;
            $order_no_time = explode('_', $order_no);
            $out_trade_no = $order_no_time[0];
            // Db::name('testmsg')->insert(['content'=>$out_trade_no,'content_data'=>1]);
            if (strpos($out_trade_no, 'JZ') !== false) {
                $model = new \app\common\model\xiservice\Order;
                $type = 0;
            } else if (strpos($out_trade_no, 'VP') !== false) {
                $model = new \app\common\model\xiservice\VipOrder;
                $type = 1;
            }else if(strpos($out_trade_no, 'DP') !== false){
                $model = new \app\common\model\xiservice\DepositOrder;
                $type = 2;
            }else if(strpos($out_trade_no, 'PX') !== false){
                $model = new \app\common\model\xiservice\TrainOrder;
                $type = 3;
            }
            if($type === 2){
               $orderInfo = Db::name('xiservice_user')->where('order_no',$out_trade_no)->find();
            }else{
                $orderInfo = $model->where('order_no', $out_trade_no)->find();

            }

            if ($message['return_code'] === 'SUCCESS') {
                // 用户是否支付成功

                if ($message['result_code'] === 'SUCCESS') {
                    $updateTransaction = [
                        'notify' => 1,
                        'transaction_id' => $transaction_id
                    ];
                    // 开始回调处理订单
                    if ($type == 0) {
                        //服务订单回调
                        //推送订阅消息
                        if($orderInfo['order_type']=='20')
                        {
                            $msg = new \app\common\model\xiservice\Message();
                            $msg->sendOrderMessage($orderInfo, 10);
                        }else{
                            $msg = new \app\common\model\xiservice\Message();
                            $msg->sendOrderMessage($orderInfo, 8);
                        }
                   
                        $user = Db::name('xiservice_user')->where('id',$orderInfo['worker_id'])->find();
                        
                        $map['pay_status'] = 20;
                        $map['order_status'] = 30;
                        $map['pay_time'] = time();
                        $map['confirm_time'] = time();
                        Db::name('xiservice_order')->where('order_no', $order_no)->update($map);
                     //   $this->updateorderamount($orderInfo);
                        if ($orderInfo['bargain'] == 0) {

                           
                            //非议价回调处理
                            $res = $model->changeOrderStatus($orderInfo['id'], 'payed');
                        } else {
                            //议价回调
                                $res = $model->changeOrderStatus($orderInfo['id'], 'bargainpay');

                        }
                    } else if ($type == 1) {
                        //包年月订单
                       
                        $res = $model->changeOrderStatus($orderInfo['id'], 'payed');
                    } else if ($type == 2) {
                        $map['bond_status'] = 1;
                        $map['transaction_id'] = $transaction_id;
                        Db::name('xiservice_user')->where('order_no', $order_no)->update($map);
                        $res = $model->changeOrderStatus($orderInfo['id'], 'payed');
                    }else if($type == 3){
                        $map['status'] = 1;
                        $a = Db::name('train_order')->where('order_no', $order_no)->update($map);
                        // Db::name('testmsg')->insert(['content'=>$order_no,'content_data'=>2]);

                        // $msg = new \app\common\model\xiservice\Message();
                        //      $msg->sendOrderMessage($orderInfo, 10);

                    }

                    //更新进入支付回调的标识
                    $res = $model->where('id', $orderInfo['id'])->update($updateTransaction);

                } else {
                    return false;
                }
            } else {
                return false;
            }

            return true;
        });

        $response->send();
    }


    // 商户号退款
    public function refund($out_trade_no, $transaction_id, $refundNumber, $totalFee, $refundFee, $refund_desc)
    {

        if ($out_trade_no) {
            $result = $this->miniapp->refund->byOutTradeNumber($out_trade_no, $refundNumber, $totalFee, $refundFee, [
                // 可在此处传入其他参数，详细参数见微信支付文档
                'refund_desc' => $refund_desc,
            ]);
        } else {
            $result = $this->miniapp->refund->byTransactionId($transaction_id, $refundNumber, $totalFee, $refundFee, [
                // 可在此处传入其他参数，详细参数见微信支付文档
                'refund_desc' => $refund_desc,
            ]);
        }
        $data = [
            "transaction_id" => $transaction_id,
            "refundNumber" => $refundNumber,
            "totalFee" => $totalFee,
            "refundFee" => $refundFee,
            "refund_desc" => $refund_desc,
            "cert" => $this->miniapp->config->cert_path,
            "appid" => $this->miniapp->config->app_id

        ];

        if ($result['return_code'] == 'FAIL') {
            return ['status' => false, 'msg' => $result['return_msg'], 'data' => $data];
        } else {
            return ['status' => true];
        }
    }


}